using System;
using System.Collections.Generic;
using System.Text;
using AntEater.ComponentModel.BuildElements;

namespace AntEater.Runtime.Services.Transformation
{

    /// <summary>
    /// Specifies an class as Build Element Transformer.
    /// </summary>
    [AttributeUsage(AttributeTargets.Class,AllowMultiple=false)]
    internal sealed class BuildElementTransformerAttribute:Attribute
    {

        private bool _isFallbackForXPathNodeType;

        /// <summary>
        /// Gets or sets a value indicating whether this is the fallback transformer for the XPathNodeType
        /// of this instance.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance is fallback for the defined XPathNodeType; otherwise, <c>false</c>.
        /// </value>
        public bool IsFallbackForXPathNodeType {
            get { return _isFallbackForXPathNodeType; }
            set { _isFallbackForXPathNodeType = value; }
        }


        private System.Xml.XPath.XPathNodeType _xPathNodeType;

        /// <summary>
        /// Gets or sets the type of the XPathNode this Transformer reads or writes.
        /// </summary>
        /// <value>The type of the X path node.</value>
        public System.Xml.XPath.XPathNodeType XPathNodeType {
            get { return _xPathNodeType; }
        }

        private Type _fallbackForChildElementsOf;

        /// <summary>
        /// Gets or sets the TransformerType for which this Transformer falls back on unknown ChildElements.
        /// </summary>
        /// <value>TransformerType for which this Transformer is Fallback on ChildElements.</value>
        public Type FallbackForChildElementsOf {
            get { return _fallbackForChildElementsOf; }
            set { _fallbackForChildElementsOf = value; }
        }

        private Type _buildElementType;

        /// <summary>
        /// Gets or sets the type of the build element.
        /// </summary>
        /// <value>The type of the build element.</value>
        public Type BuildElementType {
            get { return _buildElementType; }
        }

        private Type _childBuildElementTransformer;

        /// <summary>
        /// Gets or sets the preferred Transformer for ChildElments.
        /// </summary>
        /// <value>The child build element transformer.</value>
        public Type ChildBuildElementTransformer {
            get { return _childBuildElementTransformer; }
            set { _childBuildElementTransformer = value; }
        }


        /// <summary>
        /// Gets the build element attribute.
        /// </summary>
        /// <value>The build element attribute.</value>
        public BuildElementAttribute BuildElementAttribute {
            get {
                BuildElementAttribute attribute = null;
                BuildElementAttribute[] attributes
                    = BuildElementType.GetCustomAttributes(typeof(BuildElementAttribute), true) as BuildElementAttribute[];

                if (attributes.Length > 0) {
                    attribute = attributes[0];
                }

                return attribute;
            }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="T:TransformerAttribute"/> class.
        /// </summary>
        /// <param name="buildElementType">Type of the build element.</param>
        /// <param name="xPathNodeType">Type of the x path node.</param>
        public BuildElementTransformerAttribute(Type buildElementType, System.Xml.XPath.XPathNodeType xPathNodeType)
        {
            if (buildElementType == null) {
                throw new ArgumentNullException("buildElementType");
            }

            _buildElementType = buildElementType;
            _xPathNodeType = xPathNodeType;
        }

    }
}
